#include <Windows.h>
#include <tchar.h>


//////////////////////////////////////////////////////////////////////////
LRESULT CALLBACK WndProc(HWND hWnd, UINT nMsg, WPARAM wParam, LPARAM lParam)
{
	static UINT nStep;
	static HWND hBtnMove;
	switch (nMsg)
	{
		case WM_CREATE:
		{
			HINSTANCE hInstance = (HINSTANCE)lParam;
			hBtnMove = CreateWindow(_T("Button"), 
									_T("Move Center"), 
									WS_CHILD|WS_VISIBLE, 
									0,  
									0,
									100,
									50,
									hWnd,
									(HMENU)1001,
									hInstance,
									0);
			break;
		}
		case WM_WINDOWPOSCHANGING:
		{
			TCHAR szInfo[128];
			_stprintf(szInfo, _T("Step %d:		WM_WINDOWPOSCHANGING\n"), ++nStep);
			OutputDebugString(szInfo);
			break;
		}
		case WM_WINDOWPOSCHANGED:
		{
			TCHAR szInfo[128];
			_stprintf(szInfo, _T("Step %d:		WM_WINDOWPOSCHANGED\n"), ++nStep);
			OutputDebugString(szInfo);
			break;
		}
		case WM_MOVE:
		{
			TCHAR szInfo[128];
			_stprintf(szInfo, _T("Step %d:		WM_MOVE\n"), ++nStep);
			OutputDebugString(szInfo);
			break;	
		}
		case WM_SIZE:
		{
			TCHAR szInfo[128];
			_stprintf(szInfo, _T("Step %d:		WM_SIZE\n"), ++nStep);
			OutputDebugString(szInfo);
			break;
		}
		case WM_NCCALCSIZE:
		{
			TCHAR szInfo[128];
			_stprintf(szInfo, _T("Step %d:		WM_NCCALCSIZE\n"), ++nStep);
			OutputDebugString(szInfo);
			break;
		}
		case WM_COMMAND:
		{
			if (wParam == 1001)
			{
				UINT nSrnWidth	= GetSystemMetrics(SM_CXFULLSCREEN);
				UINT nSrnHeight	= GetSystemMetrics(SM_CYFULLSCREEN);

				RECT rtWnd;
				GetWindowRect(hWnd, &rtWnd);
				UINT nWndWidth	= (rtWnd.right - rtWnd.left);
				UINT nWndHeight = (rtWnd.bottom - rtWnd.top);
				MoveWindow(hWnd, (nSrnWidth - nWndWidth) / 2, (nSrnHeight - nWndHeight) / 2, nWndWidth, nWndHeight, TRUE);

				HWND hBtnMove = GetDlgItem(hWnd, wParam);
				UINT nBtnWidth	= 200;
				UINT nBtnHeight = 100;
				MoveWindow(hBtnMove, (nWndWidth - nBtnWidth) / 2, (nWndHeight - nBtnHeight) / 2, nBtnWidth, nBtnHeight, TRUE);
			}
			break;
		}
		case WM_DESTROY:
		{
			PostQuitMessage(0);
			break;
		}
	}

	return ::DefWindowProc(hWnd, nMsg, wParam, lParam);
}

//////////////////////////////////////////////////////////////////////////
bool RegisterWndClass(HINSTANCE hInstance, const TCHAR* szWndClass)
{
	WNDCLASSEX wcx		= {0};
	wcx.cbSize			= sizeof(WNDCLASSEX);
	wcx.hbrBackground	= (HBRUSH)GetStockObject(COLOR_APPWORKSPACE);
	wcx.hCursor			= LoadCursor(NULL, MAKEINTRESOURCE(IDC_ARROW));
	wcx.hIcon			= LoadIcon(NULL, MAKEINTRESOURCE(IDI_APPLICATION));
	wcx.hInstance		= hInstance;
	wcx.lpszClassName	= szWndClass;
	wcx.lpfnWndProc		= WndProc;
	wcx.style			= CS_VREDRAW|CS_HREDRAW;

	return (0 != RegisterClassEx(&wcx)); 
}

//////////////////////////////////////////////////////////////////////////
bool CreateWnd(HINSTANCE hInstance, const TCHAR* szClassName, const TCHAR* szWndCaption)
{
	bool bSuc	= false;
	WNDCLASS wc	= {0};
	if (NULL != szClassName && 0 != GetClassInfo(hInstance, szClassName, &wc))
	{
		HWND hWnd = CreateWindowEx(WS_EX_ACCEPTFILES, 
			wc.lpszClassName, 
			szWndCaption,
			WS_VISIBLE|WS_POPUPWINDOW|WS_CAPTION,
			0, 
			0, 
			800,
			480, 
			NULL,
			NULL,
			hInstance,
			hInstance);
		if (NULL != hWnd && IsWindow(hWnd))
		{
			ShowWindow(hWnd, SW_SHOW);
			UpdateWindow(hWnd);
			bSuc	= true;
		}
	}	

	return bSuc;

}

//////////////////////////////////////////////////////////////////////////
void RunMessageLoop()
{
	MSG Msg;
	while (GetMessage(&Msg, NULL, 0, 0))
	{
		TranslateMessage(&Msg);
		DispatchMessage(&Msg);
	}

	return;
}

//////////////////////////////////////////////////////////////////////////
BOOL WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE hPreInstance, LPTSTR szCmdLine, int nShowCmd)
{
	const TCHAR* szClsName		= _T("Win32APP");
	const TCHAR* szWndName		= _T("Demo Wnd & Control move");

	if (RegisterWndClass(hInstance, szClsName))
	{
		if (CreateWnd(hInstance, szClsName, szWndName))
		{
			RunMessageLoop();
		}
	}

	return TRUE;
}